#include <iostream>
#include <vector>
#include <memory>
#include <string>
#include <type_traits>

// 定义原子类型为字符
using Atom = char;

// 前向声明广义表类
class GList;

// 节点类型可以是原子元素或子广义表
class GListNode {
public:
    // 构造函数 - 接受原子元素
    GListNode(Atom atom) : isAtom(true), atom(atom) {}

    // 构造函数 - 接受子广义表
    GListNode(std::shared_ptr<GList> subList) : isAtom(false), subList(subList) {}

    // 判断是否为原子元素
    bool isAtomNode() const { return isAtom; }

    // 获取原子元素
    Atom getAtom() const { return atom; }

    // 获取子广义表
    std::shared_ptr<GList> getSubList() const { return subList; }

private:
    bool isAtom; // 用于区分是原子元素还是子广义表
    Atom atom;   // 原子元素
    std::shared_ptr<GList> subList; // 子广义表
};

// 广义表类定义
class GList {
public:
    // 向广义表中添加原子元素
    void addAtom(Atom atom) {
        nodes.emplace_back(std::make_shared<GListNode>(atom));
    }

    // 向广义表中添加子广义表
    void addSubList(std::shared_ptr<GList> subList) {
        nodes.emplace_back(std::make_shared<GListNode>(subList));
    }

    // 递归打印广义表
    void print() const {
        std::cout << "(";
        for (size_t i = 0; i < nodes.size(); ++i) {
            auto node = nodes[i];
            if (node->isAtomNode()) {
                std::cout << node->getAtom();
            } else {
                node->getSubList()->print();
            }
            if (i != nodes.size() - 1) {
                std::cout << ", ";
            }
        }
        std::cout << ")";
    }

private:
    // 存储节点的容器，可以是原子元素或子广义表
    std::vector<std::shared_ptr<GListNode>> nodes;
};

int main() {
    // 创建主广义表
    auto gList = std::make_shared<GList>();

    // 添加原子元素
    gList->addAtom('a');
    gList->addAtom('b');

    // 创建一个子广义表并添加原子元素
    auto subList1 = std::make_shared<GList>();
    subList1->addAtom('c');
    subList1->addAtom('d');

    // 添加子广义表到主广义表
    gList->addSubList(subList1);

    // 创建另一个子广义表并添加原子元素
    auto subList2 = std::make_shared<GList>();
    subList2->addAtom('e');

    // 添加子广义表到主广义表
    gList->addSubList(subList2);

    subList1->addSubList(subList2);

    // 打印广义表
    std::cout << "广义表: ";
    gList->print();
    std::cout << std::endl;

    return 0;
}
